package com.security.control.app.support;

import com.security.control.app.jwt.MyJwtTokenEnhancer;
import com.security.control.core.properties.OAuth2Properties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

/**
 * @author imoot@gamil.com
 * @date 2019/1/9 0009 17:13
 * app权限模块需要的bean，配置在这里的bean，业务系统都可以通过声明同名或者同类型的bean来覆盖
 */
@Configuration
public class AppSecurityBeanConfig {

    @Autowired
    private RedisConnectionFactory redisConnectionFactory;

    /**
     * 密码处理类
     */
    @Bean
    @ConditionalOnMissingBean(name = "bCryptPasswordEncoder")
    public PasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * redis的令牌仓库
     */
    @Bean
    @ConditionalOnProperty(prefix = "com.security.control",name="storeType",havingValue = "redis")
    public TokenStore redisTokenStore() {
        return new MyRedisTokenStore(redisConnectionFactory);
    }

    /**
     * 配置jwt的令牌机制
     * ConditionalOnProperty注解在这里：
     * 扫描"com.security.control.storeType"的值为"jwt"时，自定义的jwt令牌机制会生效
     * matchIfMissing=true表示如果没有找到"com.security.control.storeType"那么也会生效
     */
    @Configuration
    @ConditionalOnProperty(prefix = "com.security.control",name="storeType",havingValue = "jwt",matchIfMissing = true)
    public static class JwtTokenConfig{

        @Autowired
        private OAuth2Properties oAuth2Properties;

        @Bean
        public TokenStore jwtTokenStore(){
            return new JwtTokenStore(jwtAccessTokenConverter());
        }

        @Bean
        public JwtAccessTokenConverter jwtAccessTokenConverter(){
            JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
            accessTokenConverter.setSigningKey(oAuth2Properties.getSigningKey());
            return accessTokenConverter;
        }

        @Bean
        @ConditionalOnMissingBean(name = "jwtTokenEnhancer")
        public TokenEnhancer jwtTokenEnhancer(){
            return new MyJwtTokenEnhancer();
        }
    }

}
